﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sealight.API.Framework;
using Sealight.Core.DataAdapter;
using Sealight.Data;
using Sealight.API.Ioc;
using Sealight.Core.Domain;
using System.Reflection;
using System.Globalization;

namespace Sealight.CoreAPI
{
    public class SettingService : ISettingService
    {       
        public void AddOrUpdate(Core.DataAdapter.settings data)
        {

            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            IRepository<SettingEntity> repo = IocContainer.Container().Resolve<IRepository<SettingEntity>>();

            if (data != null)
            {
                var result = repo.GetAll();

                foreach (var d in result)
                {
                    repo.Delete(d);
                }

                IList<SettingEntity> list = new List<SettingEntity>();

                Type settingsType = data.GetType();

                //------------------------------------------------------------
                //	Enumerate through settings properties
                //------------------------------------------------------------
                foreach (PropertyInfo propertyInformation in settingsType.GetProperties())
                {
                    try
                    {
                       
                            //------------------------------------------------------------
                            //	Extract property value and its string representation
                            //------------------------------------------------------------
                            object propertyValue = propertyInformation.GetValue(data, null);
                            string valueAsString = propertyValue.ToString();

                            //------------------------------------------------------------
                            //	Format null/default property values as empty strings
                            //------------------------------------------------------------
                            if (propertyValue.Equals(null))
                            {
                                valueAsString = String.Empty;
                            }
                            if (propertyValue.Equals(Int32.MinValue))
                            {
                                valueAsString = String.Empty;
                            }
                            if (propertyValue.Equals(Single.MinValue))
                            {
                                valueAsString = String.Empty;
                            }

                            //------------------------------------------------------------
                            //	Write property name/value pair
                            //------------------------------------------------------------
                            list.Add( new SettingEntity{ SettingName = propertyInformation.Name, SettingValue= valueAsString});
                       
                    }
                    catch { }
                }


                if (list != null)
                {
                    foreach (var d in list)
                    {
                        repo.Save(d);
                    }
                }

                if (commitTrans)
                    uow.TransactionalFlush();
            }
        }
     

        public Core.DataAdapter.settings GetSettings()
        {
            settings data = new settings();
            #region start_unit_of_work
            IUnitOfWork uow = null;
            if (!UnitOfWork.IsStarted)
                uow = UnitOfWork.Start();
            else uow = UnitOfWork.Current;
            #endregion
            bool commitTrans = false;
            if (!uow.IsInActiveTransaction)
            {
                //if not in active transaction
                //then begin transaction and commit it later
                uow.BeginTransaction(); //start transaction
                commitTrans = true;
            }

            IRepository<SettingEntity> repo = IocContainer.Container().Resolve<IRepository<SettingEntity>>();
            var result = repo.GetAll();

            if (result != null)
            {
                foreach (var d in result)
                {
                    var name = d.SettingName;
                    var value = d.SettingValue;

                    //------------------------------------------------------------
                    //	Enumerate through public properties of this instance
                    //------------------------------------------------------------
                    foreach (PropertyInfo propertyInformation in data.GetType().GetProperties())
                    {
                        //------------------------------------------------------------
                        //	Determine if configured setting matches current setting based on name
                        //------------------------------------------------------------
                        if (propertyInformation.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
                        {
                            //------------------------------------------------------------
                            //	Attempt to apply configured setting
                            //------------------------------------------------------------
                            try
                            {
                                propertyInformation.SetValue(data, Convert.ChangeType(value, propertyInformation.PropertyType, CultureInfo.CurrentCulture), null);
                            }
                            catch
                            {
                                // TODO: Log exception to a common logging framework?
                            }
                            break;
                        }
                    }
                }
            }

            return data;

        }
    }
}
